﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using BTS.COMMON;
using System.Data.Common;
using System.Reflection;
using pagination;

namespace BTS.DAL
{
    public class ObjectDALBase
    {
        protected MSDBHelper GetDBHelper(string connectionString, string providerName)
        {
            MSDBHelper dbHelper = null;
            if (string.IsNullOrEmpty(connectionString) && string.IsNullOrEmpty(providerName))
            {
                dbHelper = new MSDBHelper();
            }
            if (!string.IsNullOrEmpty(connectionString) && !string.IsNullOrEmpty(providerName))
            {
                dbHelper = new MSDBHelper(connectionString, providerName);
            }
            if (!string.IsNullOrEmpty(connectionString) && string.IsNullOrEmpty(providerName))
            {
                dbHelper = new MSDBHelper(connectionString);
            }
            return dbHelper;
        }

        protected DbCommand GetCommand(MSDBHelper dbHelper, CommandType cmdType, string cmdText)
        {
            DbCommand cmd = null;
            switch (cmdType)
            {
                case CommandType.Text:
                    cmd = dbHelper.GetSqlStringCommand(cmdText);
                    break;
                case CommandType.StoredProcedure:
                    cmd = dbHelper.GetStoredProcCommand(cmdText);
                    break;
                default:
                    break;
            }
            return cmd;
        }
        #region
        /// <summary>
        /// 添加删除修改
        /// </summary>
        /// <param name="connectionString">数据库连接字符串</param>
        /// <param name="providerName">数据库类型</param>
        /// <param name="cmdType">执行类型</param>
        /// <param name="cmdText">执行语句或存储过程名称</param>
        /// <param name="cmdParams">参数</param>
        /// <returns>是否成功</returns>
        public bool AddOrUpdateOrDelete(string connectionString, string providerName, CommandType cmdType, string cmdText, DbParameter[] cmdParams)
        {
            MSDBHelper dbHelper = GetDBHelper(connectionString, providerName);
            DbCommand cmd = GetCommand(dbHelper, cmdType, cmdText);
            dbHelper.AddParameterCollection(cmd, cmdParams);
            int i = dbHelper.ExecuteNonQuery(cmd);
            return i > 0;
        }
        #endregion

        #region 获取单行单列
        /// <summary>
        /// 获取数量,用于得到某些数据条数或者判断是否存在指定数据
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="strSql"></param>
        /// <returns>数量</returns>
        public object ExecuteScalar(string connectionString, string providerName, CommandType cmdType, string cmdText, DbParameter[] cmdParams)
        {
            MSDBHelper dbHelper = GetDBHelper(connectionString, providerName);
            DbCommand cmd = GetCommand(dbHelper, cmdType, cmdText);
            dbHelper.AddParameterCollection(cmd, cmdParams);
            return dbHelper.ExecuteScalar(cmd);
        }
        #endregion

        #region
        /// <summary>
        /// 获取对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connectionString"></param>
        /// <param name="providerName"></param>
        /// <param name="cmdType"></param>
        /// <param name="cmdText"></param>
        /// <param name="cmdParams"></param>
        /// <returns></returns>
        public object GetObject<T>(string connectionString, string providerName, CommandType cmdType, string cmdText, DbParameter[] cmdParams) where T : new()
        {
            MSDBHelper dbHelper = GetDBHelper(connectionString, providerName);
            DbCommand cmd = GetCommand(dbHelper, cmdType, cmdText);
            dbHelper.AddParameterCollection(cmd, cmdParams);
            List<T> list = SetQueryDataCollectionValue<T>(dbHelper.ExecuteReader(cmd));
            if (list.Count > 0)
                return list[0];
            else
                return null;
        }
        #endregion

        #region 获取列表
        /// <summary>
        /// 获取列表
        /// </summary>
        /// <typeparam name="T">范型，不指定具体对象</typeparam>
        /// <param name="connectionString">数据库连接字符串</param>
        /// <param name="strSql">执行语句</param>
        /// <returns>范型集合</returns>
        public List<T> GetList<T>(string connectionString, string providerName, CommandType cmdType, string cmdText, DbParameter[] cmdParams) where T : new()
        {
            MSDBHelper dbHelper = GetDBHelper(connectionString, providerName);
            DbCommand cmd = GetCommand(dbHelper, cmdType, cmdText);
            dbHelper.AddParameterCollection(cmd, cmdParams);
            List<T> list = SetQueryDataCollectionValue<T>(dbHelper.ExecuteReader(cmd));
            return list;
        }

        /// <summary>
        /// 获取分页列表
        /// </summary>
        /// <typeparam name="T">范型，不指定具体对象</typeparam>
        /// <param name="connectionString">数据库连接字符串</param>
        /// <param name="strSql">执行语句</param>
        /// <returns>范型集合</returns>
        public List<T> GetList<T>(string connectionString, string providerName, ref PageStructure ps, DbParameter[] cmdParams) where T : new()
        {
            MSDBHelper dbHelper = GetDBHelper(connectionString, providerName);
            DbCommand cmd = GetCommand(dbHelper, CommandType.StoredProcedure, "sp_Pagination");
            dbHelper.AddParameterCollection(cmd, cmdParams);
            DbDataReader dr = dbHelper.ExecuteReader(cmd);
            List<T> list = new List<T>();
            if (dr.Read())
            {
                ps.Counts = Convert.ToInt32(dr["n"]);//总记录数
            }
            if (ps.Counts > 0)
            {
                dr.NextResult();
                list = SetQueryDataCollectionValue<T>(dr);
            }
            return list;
        }
        #endregion

        #region
        private static List<T> SetQueryDataCollectionValue<T>(DbDataReader readerData) where T : new()
        {
            List<T> listData = new List<T>();
            Type typeData = typeof(T);
            string strDataColumnName = "";
            try
            {
                while (readerData.Read())
                {
                    T itemData = new T();
                    for (int i = 0; i < readerData.FieldCount; i++)
                    {
                        strDataColumnName = readerData.GetName(i);
                        if (!string.IsNullOrEmpty(strDataColumnName))
                        {
                            PropertyInfo pi = typeData.GetProperty(strDataColumnName);
                            Type typeColumn = readerData.GetFieldType(i);
                            if (readerData[strDataColumnName] != DBNull.Value && readerData[strDataColumnName].ToString() != "")
                            {
                                string strBuffer = "", strFieldValue;
                                strFieldValue = readerData[strDataColumnName].ToString();

                                if (typeColumn.Name.ToUpper().Contains("INT") || typeColumn.Name.ToUpper().Contains("DECIMAL"))
                                {
                                    if (typeColumn.Name.ToUpper().Contains("INT"))
                                        pi.SetValue(itemData, Convert.ToInt32(strFieldValue), null);
                                    if (typeColumn.Name.ToUpper().Contains("DECIMAL"))
                                        pi.SetValue(itemData, Convert.ToDecimal(strFieldValue), null);
                                }
                                else
                                {
                                    strBuffer = strFieldValue;
                                    pi.SetValue(itemData, strBuffer, null);
                                }
                            }
                            else
                            {
                                if (typeColumn.Name.ToUpper().Contains("INT") || typeColumn.Name.ToUpper().Contains("DECIMAL"))
                                {
                                    pi.SetValue(itemData, 0, null);
                                }
                                else
                                    pi.SetValue(itemData, "", null);
                            }
                        }
                    }
                    listData.Add(itemData);
                }
            }
            catch (Exception ex)
            {
                BTSLog.DoLog("BTS.DAL.ObjectDALBase 方法：SetQueryDataCollectionValue", "strDataColumnName=" + strDataColumnName + "\r\n" + ex.Message, ex.StackTrace);
            }
            finally
            {
                readerData.Close();
            }
            return listData;
        }
        #endregion
    }
}
